package cn.green.aop.busi;

import cn.green.annotations.busi.Business;
import cn.green.annotations.busi.Function;
import cn.green.interaction.response.builder.HttpResponseBuilder;
import cn.green.interaction.response.module.HttpResponse;
import cn.green.interaction.response.enums.InteractionResult;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;

import java.lang.reflect.Method;

/**
 * 抽象类：业务切面
 */
@Aspect
@Component
@Lazy(false)
public class BusinessAop {

    //切点为标注了Function注解的方法
    @Pointcut("@annotation(cn.green.annotations.busi.Function)")
    public void pointCut() {}

    /**
     * 环绕通知
     * @param joinPoint
     * @return
     */
    @Around("pointCut()")
    public Object doBusiness(ProceedingJoinPoint joinPoint) {
        //1.获取到切入点的方法
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        //2.获取方法所属的class类
        Class<?> declaringClass = method.getDeclaringClass();
        //获取Controller注解
        Controller controller = declaringClass.getDeclaredAnnotation(Controller.class);
        if (controller == null) {
            //如果没有Controller注解，则说明不是Controller层，直接抛异常
        }
        //获取Business注解
        Business business = declaringClass.getDeclaredAnnotation(Business.class);
        if (business == null) {
        }
        //获取Function注解
        Function function = method.getDeclaredAnnotation(Function.class);
        try {
            //执行目标方法
            Object proceed = joinPoint.proceed(joinPoint.getArgs());
            //返回交互-响应模型（响应状态、响应数据，响应消息，响应结果）
            return HttpResponseBuilder.buildResponse(HttpStatus.OK, proceed, "", InteractionResult.SUCCESS);
        }  catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return null;
    }
}
